/* Copyright (c) 2004-2008, Andriy Nikolov
 * All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.processmining.importing.email;

import org.kxml2.io.*;
import org.kxml2.kdom.*;
import org.processmining.framework.log.*;
import org.xmlpull.v1.*;
import org.processmining.email.*;
import java.io.*;
import java.util.*;
import java.text.*;

/**
 * @author not attributable
 * @version 1.0
 */
public class EMailLogReader {
  public EMailLogReader() {
    try {
      jbInit();
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  static EMailMessage currentMessage = new EMailMessage();
  static EMailLog eMailLog;
  static String value;
  static String id;
  static String address;

  static boolean messageBeingSaved = false;
  static boolean charactersStarted = false;
  static String currentElement;

  static final int ELEMENT_NONE = 0;
  static final int ELEMENT_FROM = 1;
  static final int ELEMENT_TO = 2;
  static final int ELEMENT_CC = 3;
  static final int ELEMENT_BCC = 4;
  static final int ELEMENT_SUBJECT = 5;
  static final int ELEMENT_CASE = 6;
  static final int ELEMENT_TASK = 7;
  static final int ELEMENT_PHASE = 8;
  static final int ELEMENT_SENTON = 9;
  static final int ELEMENT_EMAILLOG = 10;
  static final int ELEMENT_MESSAGE = 11;
  static final int ELEMENT_ERROR = 12;

  XmlPullParser parser;
  XmlPullParserFactory factory;

  public void setEMailLog(EMailLog log) {
    eMailLog = log;
    LogReader k;
  }

  public EMailLogReader(InputStream input) {
    try {
      System.setProperty("org.xmlpull.v1.XmlPullParserFactory", "org.kxml2.io.KXmlParser");
      factory = XmlPullParserFactory.newInstance(System.getProperty("org.xmlpull.v1.XmlPullParserFactory"), null);
      factory.setNamespaceAware(true);
      parser = factory.newPullParser();
      parser.setInput(input, "UTF-8");
    } catch (XmlPullParserException xmlException) {
      xmlException.printStackTrace();
    }
  }

  public void parse() {
    int eventType;
    try {
      eventType = parser.getEventType();
      do {
        switch(eventType) {
          case XmlPullParser.START_DOCUMENT:
            startDocument();
            break;
          case XmlPullParser.START_TAG:
            startElement();
            break;
          case XmlPullParser.TEXT:
            processText();
            break;
          case XmlPullParser.END_TAG:
            endElement();
        }
        eventType = parser.next();
      } while(eventType!=XmlPullParser.END_DOCUMENT);
    } catch (XmlPullParserException xmlException) {
      xmlException.printStackTrace();
    } catch (IOException ioException) {
      ioException.printStackTrace();
    }
  }

  private void startDocument() {

  }

  private void processText() {
    int[] arrayStartAndLength = new int[2];
    char ch[];
    int start, length;
    ch = parser.getTextCharacters(arrayStartAndLength);
    start = arrayStartAndLength[0];
    length = arrayStartAndLength[1];
    if (!messageBeingSaved)
      return;
    if (!charactersStarted) {
      value = new String(ch, start, length);
    } else {
      value = value + new String(ch, start, length);
    }
//    value = value.trim();
//    System.out.println("Value: "+value);
//    System.out.println("Start: "+start);
//    System.out.println("Length: "+length);

//    if((value.length()>0)&&(value.length()-start>length)) {
//      value = value.substring(start, length);
//    }
    charactersStarted = true;
  }

  private void startElement() {
    String localName = parser.getName();
    if (localName.equals("Message")) {
      id = parser.getAttributeValue("", "messageId");
      if(!eMailLog.getMessageList().containsKey(id)) {
        messageBeingSaved = true;
        currentMessage = new EMailMessage();
        currentMessage.setId(id);
      } else {
        messageBeingSaved = false;
      }
    }
    if (messageBeingSaved) {
      currentElement = localName;
      if(currentElement.equals("To")||currentElement.equals("Cc")||currentElement.equals("Bcc"))
        address = parser.getAttributeValue("", "address");
      if (address==null)
        address = "";
      charactersStarted = false;
    }
  }

  private void endElement() {
    EMailRecipient user;
    Date sentOn;
    DateFormat df;
    value = value.trim();
    if(messageBeingSaved) {
      if (currentElement.equals("From")) {
        user = eMailLog.createEMailRecipient(value, address);
        currentMessage.setFrom(user);
      }
      if (currentElement.equals("To")) {
        user = eMailLog.createEMailRecipient(value, address);
        currentMessage.addTo(user);
      }
      if (currentElement.equals("Cc")) {
        user = eMailLog.createEMailRecipient(value, address);
        currentMessage.addCc(user);
      }
      if (currentElement.equals("Bcc")) {
        user = eMailLog.createEMailRecipient(value, address);
        currentMessage.addBcc(user);
      }
      if (currentElement.equals("Subject")) {
        currentMessage.setSubject(value);
      }
      if (currentElement.equals("Case")) {
        currentMessage.setCase(value);
      }
      if (currentElement.equals("Task")) {
        currentMessage.setTask(value);
      }
      if (currentElement.equals("Phase")) {
        currentMessage.setPhase(value);
      }
      if (currentElement.equals("SentOn")) {
        df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT,
                                            Locale.UK);
        try {
          value = value.replace('/', '.');
          value = value.replace('-', '.');
          sentOn = df.parse(value);
          currentMessage.setSentOn(sentOn);
        }
        catch (ParseException pe) {
          try {
            value = value.replace('.', '/');
            value = value.replace('-', '/');
            sentOn = df.parse(value);
            currentMessage.setSentOn(sentOn);
          }
          catch (ParseException pe2) {
            try {
              value = value.replace('.', '-');
              value = value.replace('/', '-');
              sentOn = df.parse(value);
              currentMessage.setSentOn(sentOn);
            }
            catch (ParseException pe3) {
              pe3.printStackTrace();
            }
          }
        }
      }
      if(parser.getName().equals("Message")) {
        if(currentMessage.getFrom()==null) {
          user = eMailLog.createEMailRecipient("", "");
//          user.setActive(false);
          currentMessage.setFrom(user);
        }
        eMailLog.addMessage(currentMessage);
        messageBeingSaved = false;
      }
    }

    currentElement = "None";
    address = "";
    charactersStarted = false;
  }

  private void jbInit() throws Exception {
  }
}
